# Rust on Maemo

Everyone wants to run Rust on their phone, right?

But it's not so easy when your pocket device is the Nokia N900. You'd think that I should be using the Librem 5, but my pockets disagree. Actually, I agree with them, too, at least as long as I use the device to collect GPS tracks.

The phone is over 10 years old by this point, and it's not open, which means it's running outdated software. Nokia stopped supporting Maemo around 2011, and the last community update happened a couple of years ago too. Despite that, I'd like to run some of my own code on it. The canonical way to do it is to use the SDK via a Docker image, but it's rather clumsy.

## GNU libc

My first attempt to compile code for the N900 was to use a recent version of Debian, running on an emulated ARM CPU. It didn't go far: after copying to the phone, the program failed to run. Glibc is too old.

Easy, I thought! I can always package up glibc together with the program via static linking. As I tried it out, I was greeted with a crash message along the lines of:

> This kernel is too old.

Jolly, so Linux version 2.6.28 doesn't meet modern standards. It seems my road is blocked, and this was just a "hello world" C program.

## Musl

A while later, I realized that the kernel complaint probably came from glibc as well. But Rust doesn't have to use glibc, it can also use musl as the C library! Let's check Rust's platform support page. The CPU on the N900 supports the ARMv7 instruction set, so we're looking for `armv7-unknown-linux-`. And here we go: apart from `armv7-unknown-linux-gnueabi`, indicating the usage of glibc, there's also `armv7-unknown-linux-musleabi` for musl.

Looking closer at musl's FAQ page and the section on requirements:

> Linux 2.6 or later.

Awesome! That means our ancient kernel is supported.

Rust has the ability to cross-compile, which makes testing the solution easy. I picked up [my earlier project] related to the N900, added a `.cargo/config` file, and typed in the following commands:

```
dnf install -y gcc # needed for syn at compile time
dnf install -y lld # no armel gcc toolchain for Fedora, so use clang linker cause it does armel out of the box
curl https://sh.rustup.rs -sSf | sh -s -- -t armv7-unknown-linux-musleabi
cd /mnt/src/grconverter
source $HOME/.cargo/env
cargo build --target armv7-unknown-linux-musleabi
cp target/armv7-unknown-linux-musleabi/debug/read /mnt/n900 # copy onto the phone
```

…and it's alive!

```
$ ./read MyDocs/gpsrecorder/gpstrack-20210804-140132.gpsr | head
Header(
    Header {
        magic: [
            71,
            80,
            83,
            82,
        ],
        format: 3,
        time: 1628078492,
```

Or at least half-alive. Linking to external libraries is still an open question, but the standard library works, which means pure-Rust crates are good to go.

Happy hacking!

dcz's projects

Thoughts on software and society.

Atom feed